/*
 * @Author: ly
 * @Date: 2019-10-01 16:31:28
 * @Last Modified by: inter
 * @Last Modified time: 2020-06-02 18:23:52
 */
import React from 'react';
import Immutable from 'immutable';

import { connect, DispatchProp } from 'react-redux';
import { NextPageContext } from 'next';
import merge from 'classnames';
import { IRootState } from '../../reducers';

import ActionTypes from '../../actions/redpacket-rain';
import RoomActions from '../../actions/room';
import SensorsDataActions from '../../actions/sensors-data';

import SimpleModal from './simple-modal';
import SimpleModalActions from '../../actions/simple-modal';

import Items from './items';
import Result from './result';

import logger from '../../utils/logger';

import css from './index.less';
import { trimString, checkReg, getSeconds } from './utils/functions';

let interval: any = null;
// let count = 0;

interface IProps {
  redpacketRain: Immutable.Map<string, any>;
  roomInfo: Immutable.Map<string, any>;
  simpleModal: Immutable.Map<string, any>;
}

interface IRedpacketRainProps {
  id: number;
  isAll: boolean;
  roomId: number;
  anchorId: number;
  logo: string;
  title: string;
  state: number;
  isRecieved: boolean;
  isLastRecieved: boolean;
  lastEndTime: number;
  startTime: number;
  endTime: number;
  curTime: number;

  // layer
  layerVisible: boolean;
  layerOpacity: number;

  // countdown
  countdown: number;

  // duration
  duration: number;

  // result
  resultVisible: boolean;
  resultCover: boolean;
  resultContentTags: [];
  resultAd: string;
  resultAdUrl: string;
  resultClickHandler: string;
}

interface ISimpleModalProps {
  visible: boolean;
  title: string;
  content: string | JSX.Element;
  btnNum: number;
  confirmHandler?: () => void;
  closeHandler?: () => void;
}

interface IState {
  // status
  countdown: number;
  duration: number;
  // form
  name: string;
  mobile: string;
  address: string;
}

class RedpacketRain extends React.PureComponent<IProps & DispatchProp> {
  public state: IState = {
    // status
    countdown: -1,
    duration: -1,
    // form
    name: '',
    mobile: '',
    address: '',
  };

  public static getInitialProps = async ({ store, query }: NextPageContext) => {
    store.dispatch({ type: RoomActions.ROOM_INFO, payload: { roomId: Number(query.roomid) || 1000000000 } });
    return {};
  };

  public static getDerivedStateFromProps = (nextProps: IProps, prevState: IState) => {
    // console.log('getDerivedStateFromProps',prevState, nextProps);
    const props: IRedpacketRainProps = nextProps.redpacketRain.toJS() as IRedpacketRainProps;
    const state: IState = prevState;
    if (props.countdown && ((props.countdown > 0 && prevState.countdown < 0) || (props.countdown < 0 && prevState.countdown > 0))) {
      state.countdown = props.countdown;
    }
    if (props.duration && ((props.duration > 0 && prevState.duration < 0) || (props.duration < 0 && prevState.duration > 0))) {
      state.duration = props.duration;
    }
    return state;
  };

  // shouldComponentUpdate = (nextProps: IredpacketRainProps /* , prevState:IState */) => {
  //     const props: IProps = nextProps.redpacketRain.toJS();
  //     const prevProps: IProps = this.props.redpacketRain.toJS();
  //     // 房间和红包状态没有改变
  //     if (prevProps.roomId === props.roomId && prevProps.anchorId === props.anchorId && prevProps.id === props.id && prevProps.state === props.state ) {
  //         return false;
  //     }
  //     return true;
  // }

  render() {
    const props: IRedpacketRainProps = this.props.redpacketRain.toJS() as IRedpacketRainProps;
    const modal: ISimpleModalProps = this.props.simpleModal.toJS() as ISimpleModalProps;
    // console.log('renderLayer', props.layerVisible, ++count);
    return (
      <>
        {props.layerVisible && (
        <div
          className={css.layer}
          style={{ opacity: props.layerOpacity }}
          onClick={(event) => {
            event.stopPropagation();
          }}
        >
          {this.state.countdown >= 0 && (
          <div className={merge(css.countdown, css[`num${this.state.countdown > 3 ? 4 : this.state.countdown}`])} />
          )}
          {this.state.duration >= 0 && this.state.countdown < 0 && (
          <div className={css.duration}>
            剩余
            <span className={css.remainingSeconds}>{this.state.duration}</span>
            秒
          </div>
          )}
          <Items duration={props.duration} countdown={this.state.countdown} catchRedpacket={this.catchRedpacket} />
          {props.resultVisible && (
          <Result
            cover={props.resultCover}
            coverLogo={props.logo}
            coverTitle={props.title}
            coverContent="恭喜发财，大吉大利"
            coverClickHandler={this.catchRedpacket}
            contentTags={props.resultContentTags}
            clickHandler={() => {
              props.resultClickHandler === 'hideLayer' && this.hideLayer();
            }}
          />
          )}
        </div>
        )}
        {this.tipVisible(props) && <a className={css.tip} href={`/${props.roomId}`} target="_blank" rel="noopener noreferrer" />}
        <SimpleModal
          visible={modal.visible}
          title={modal.title}
          content={modal.content}
          btnNum={modal.btnNum}
          confirmHandler={modal.confirmHandler}
          closeHandler={modal.closeHandler}
        />
      </>
    );
  }

  componentDidMount() {
    const redpacketRainInfoStr = localStorage.getItem('redpacketRainInfo');
    const redpacketRainInfo = redpacketRainInfoStr ? JSON.parse(redpacketRainInfoStr) : {};
    const roomId = this.props.roomInfo.get('room_id');
    const anchorId = this.props.roomInfo.get('owner_uid');
    if (redpacketRainInfo.timestamp) {
      if (new Date().getTime() - redpacketRainInfo.timestamp > 24 * 60 * 60 * 1000) {
        localStorage.removeItem('redpacketRainInfo');
      } else if (redpacketRainInfo.roomId === Number(roomId)) {
        this.props.dispatch({
          type: ActionTypes.REDPACKET_RAIN_INFO_LOCAL,
          payload: { redpacketRainInfo },
        });
        return;
      }
    }
    this.props.dispatch({
      type: ActionTypes.REDPACKET_RAIN_INFO,
      payload: {
        roomId: Number(roomId),
        anchorId: Number(anchorId),
      },
    });
  }

  // public getSnapshotBeforeUpdate = (prevProps: IProps, prevState: IState) => {
  //     console.log('getSnapshotBeforeUpdate',prevProps，prevState,this.state)
  //     // 返回将被作为 componentDidUpdate 的第三个参数传入
  //     return null
  // };

  componentDidUpdate(prevProps: IProps /* prevState: IState,  snapshot:any */) {
    // console.log('componentDidUpdate',prevProps,prevState,snapshot,this.state)
    const prevResultVisible = prevProps.redpacketRain.get('resultVisible');
    const resultVisible = this.props.redpacketRain.get('resultVisible');
    if (!prevResultVisible && resultVisible) {
      setTimeout(() => {
        this.props.dispatch({
          type: ActionTypes.REDPACKET_RAIN_COMMON,
          payload: {
            resultClickHandler: 'hideLayer',
          },
        });
      }, 2000);
    }

    clearInterval(interval);
    interval = setInterval(() => {
      const {countdown} = this.state;
      const {duration} = this.state;
      if (countdown >= 0) {
        this.setState({
          countdown: countdown - 1,
        });
        if (countdown === 0) {
          this.props.dispatch({
            type: ActionTypes.REDPACKET_RAIN_COMMON,
            payload: {
              countdown: -1,
            },
          });
        }
      } else if (duration >= 0) {
        this.setState({
          duration: duration - 1,
        });
        if (duration === 0) {
          this.props.dispatch({
            type: ActionTypes.REDPACKET_RAIN_COMMON,
            payload: {
              duration: -1,
            },
          });
          const layerVisible = this.props.redpacketRain.get('layerVisible');
          // 如果是 tip 则不显示
          if (layerVisible) {
            this.missRedpacket();
          }
        }
      }
    }, 1000);
  }

  // componentWillUnmount() {
  //     clearInterval(interval);
  //     interval = null;
  // }

  public catchRedpacket = () => {
    logger.info('抢红包');
    const props: IRedpacketRainProps = this.props.redpacketRain.toJS() as IRedpacketRainProps;
    const roomId = this.props.roomInfo.get('room_id');
    const anchorId = this.props.roomInfo.get('owner_uid');
    this.props.dispatch({
      type: ActionTypes.REDPACKET_INFO,
      payload: {
        roomId: Number(roomId),
        anchorId: Number(anchorId),
        props: {
          id: props.id,
          isAll: props.isAll,
          roomId: props.roomId,
          anchorId: props.roomId,
          logo: String(props.logo),
          title: String(props.title),
        },
        showForm: this.showForm,
        sensorsDataTrack: this.sensorsDataTrack,
      },
    });
  };

  public missRedpacket = () => {
    logger.info('隐藏 duration items');
    logger.info('显示 result');
    this.props.dispatch({
      type: ActionTypes.REDPACKET_RAIN_COMMON,
      payload: {
        resultVisible: true,
        resultCover: false,
        resultContentTags: [
          {
            className: 'topTxt',
            innerHTML: '哎呀，运气不好!\n没关系等下次一定可以中奖的~',
          },
          {
            className: 'bottomTxt',
            innerHTML: '再接再厉',
          },
        ],
      },
    });
    logger.info('2秒后 layer 点击隐藏');
  };

  private readonly hideLayer = () => {
    logger.info('隐藏 layer');
    this.props.dispatch({
      type: ActionTypes.REDPACKET_RAIN_COMMON,
      payload: {
        resultVisible: false,
        modalVisible: false,
        layerVisible: false,
        layerOpacity: 0,
      },
    });
  };

  private readonly showForm = () => {
    this.props.dispatch({
      type: SimpleModalActions.SIMPLE_MODAL,
      payload: {
        visible: true,
        title: '填写中奖信息',
        content: (
          <div key="form" className={css.form}>
            <div key="name" className={css.group}>
              <label key="labelName">姓名：</label>
              <input key="inputName" name="name" onChange={this.changeForm} type="text" />
              <p key="infoName">请填写您的真实姓名</p>
            </div>
            <div key="mobile" className={css.group}>
              <label key="labelMobile">手机号码：</label>
              <input key="inputMobile" name="mobile" onChange={this.changeForm} type="text" />
              <p key="infoMobile">请填写正确的手机号码</p>
            </div>
            <div key="address" className={css.group}>
              <label key="labelAddress">收货地址：</label>
              <input key="inputAddress" name="address" onChange={this.changeForm} type="text" />
              <p key="infoAddress">请填写您正确的收货地址</p>
            </div>
          </div>
        ),
        btnNum: 2,
        confirmHandler: this.submitForm,
      },
    });
  };

  private readonly changeForm = (event: any) => {
    // console.log('changeForm',event.target.name,event.target.value);
    if (!checkReg(event.target.name, event.target.value)) {
      event.target.parentNode.className = merge(css.group, css.warning);
    } else {
      event.target.parentNode.className = css.group;
    }
    this.setState({
      [event.target.name]: event.target.value,
    });
  };

  private readonly submitForm = () => {
    const formData: any = {
      name: trimString(this.state.name),
      mobile: trimString(this.state.mobile),
      address: trimString(this.state.address),
    };

    let checkForm = true;
    for (const key in formData) {
      if (!checkReg(key, formData[key])) {
        checkForm = false;
        break;
      }
    }

    // console.log('submitForm', formData, checkForm);

    if (checkForm) {
      this.props.dispatch({
        type: ActionTypes.REDPACKET_FORM_SUBMIT,
        payload: {
          formData,
        },
      });
      this.props.dispatch({ type: SimpleModalActions.SIMPLE_MODAL, payload: { visible: false } });
    }
  };

  private readonly tipVisible = (props: IRedpacketRainProps) => {
    const roomId = this.props.roomInfo.get('room_id');
    return Number(roomId) !== props.roomId && !props.isAll && getSeconds(props.countdown, props.duration) > 0;
  };

  private readonly sensorsDataTrack = (param: { eventName: string; eventDesc: any }) => {
    this.props.dispatch({
      type: SensorsDataActions.SENSORS_DATA_TRACK,
      payload: param,
    });
  };
}
export default connect((state: IRootState) => ({
  redpacketRain: state.get('redpacketRain').get('redpacketRain'),
  roomInfo: state.get('roomInfo').getIn(['roomInfo', 'room_info']),
  simpleModal: state.get('simpleModal'),
}))(RedpacketRain);
